<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>推迟分片分配 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/_delaying_shard_allocation.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/_delaying_shard_allocation.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_delaying_shard_allocation.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/_delaying_shard_allocation.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="administration.html">管理、监控和部署</a></span>
»
<span class="breadcrumb-link"><a href="post_deploy.html">部署后</a></span>
»
<span class="breadcrumb-node">推迟分片分配</span>
</div>
<div class="navheader">
<span class="prev">
<a href="indexing-performance.html">« 索引性能技巧</a>
</span>
<span class="next">
<a href="_rolling_restarts.html">滚动重启 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="_delaying_shard_allocation"></a>推迟分片分配 (Delaying Shard Allocation)<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/520_Post_Deployment/35_delayed_shard_allocation.asciidoc">edit</a>
</h2>
</div></div></div>
<p>正如我们在 <a class="xref" href="_scale_horizontally.html" title="水平扩容">水平扩容</a> 讨论过的， Elasticsearch 将自动在可用节点间进行分片均衡，包括新节点的加入和现有节点的离线。</p>

<p>从理论上来说，这是最好的做法，我们想要提拔副本分片来尽快恢复丢失的主分片。
我们同时也希望保证资源在整个集群的均衡，以防出现热点。</p>

<p>然而，在实践中，立即的再均衡所造成的问题会比其解决的更多。例如，考虑一下这种情况：</p>
<div class="olist orderedlist">
<ol class="orderedlist">
<li class="listitem">
节点 node-19 在网络中失联了（某个家伙踢到了电源线)
</li>
<li class="listitem">
Master 立即注意到了这个节点的离线，它决定在集群内提拔其他拥有 node-19 上面的主分片对应的副本分片为主分片
</li>
<li class="listitem">
在副本分片被提拔为主分片以后，master 节点开始执行恢复操作来重建缺失的副本。

集群中的节点之间互相拷贝分片数据，网卡压力剧增，集群状态尝试变绿。
</li>
<li class="listitem">
由于目前集群处于非平衡状态，这个过程还有可能会触发小规模的分片移动。

其他不相关的分片将在主机间迁移来达到更好的平衡状态
</li>
</ol>
</div>

<p>与此同时，那个踢到电源线的倒霉管理员，把电源线插好。node-19 重新启动并加入集群。

不幸的是，这个节点被告知当前的数据已经没有用了，数据已经在其他节点上重新分配了。

所以 node-19 把本地的数据进行删除，然后重新开始恢复集群的其他分片（然后这又导致了一个新的再平衡）</p>

<p>如果这一切听起来是不必要的且开销极大，那就对了。

是的，不过前提是你知道这个节点会很快回来。

如果节点 node-19 真的丢了，上面的流程确实正是我们想要发生的。</p>

<p>为了解决这种瞬时中断的问题，Elasticsearch 有了推迟分片分配的能力。

这使集群有时间查看节点是否会在开始重新平衡之前重新加入。</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_修改默认延时"></a>修改默认延时<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/520_Post_Deployment/35_delayed_shard_allocation.asciidoc">edit</a>
</h3>
</div></div></div>
<p>默认情况，集群会等待一分钟来查看节点是否会重新加入。

如果这个节点在计时器过期之前重新加入，重新加入的节点会保持其现有的分片数据，不会发生分片分配。</p>

<p>默认等待时间可以全局设置，也可以在索引级别进行修改，都是修改配置<code class="literal">delayed_timeout</code>:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /_all/_settings <a id="CO308-1"></a><i class="conum" data-value="1"></i>
{
  "settings": {
    "index.unassigned.node_left.delayed_timeout": "5m" <a id="CO308-2"></a><i class="conum" data-value="2"></i>
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO308-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>通过使用 <code class="literal">_all</code> 索引名，我们可以为集群里面的所有的索引使用这个参数</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO308-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>默认时间被修改成了 5 分钟</p>
</td>
</tr>
</table>
</div>
<p>这个配置是动态的，可以在运行时进行修改。

如果你希望分片立即分配而不想等待，你可以设置参数： <code class="literal">delayed_timeout: 0</code>.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>延迟分配不会阻止副本被提拔为主分片。集群还是会进行必要的提拔来让集群回到 <code class="literal">yellow</code> 状态。缺失副本的分配是唯一被延迟的过程。</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_自动取消分片迁移"></a>自动取消分片迁移<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/520_Post_Deployment/35_delayed_shard_allocation.asciidoc">edit</a>
</h3>
</div></div></div>
<p>如果节点在超时之后再回来，且集群还没有完成分片的移动，会发生什么事情呢？

在这种情形下，Elasticsearch 会检查该机器磁盘上的数据和主分片上的当前<em>活(live)</em>的数据是不是一样 — 如果两者匹配，
说明没有进来新的文档，修改和删除 — 那么 master 将会取消正在进行的再平衡，并恢复该机器磁盘上的数据。</p>

<p>之所以这样做是因为本地磁盘的恢复永远要比网络间传输要快，并且因为我们可以保证分片上的数据是一样的，这个过程就是双赢的。</p>

<p>如果分片已经产生了分歧（比如：节点离线之后又索引了新的文档），则恢复进程将继续如常进行。重新加入的节点会删除本地的、过时的分片，然后获取一份新的。</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="indexing-performance.html">« 索引性能技巧</a>
</span>
<span class="next">
<a href="_rolling_restarts.html">滚动重启 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>